package com.codeplex.jtfscli.commands;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.codeplex.jtfscli.util.TFSConnectionFactory;
import com.microsoft.tfs.core.clients.versioncontrol.VersionControlConstants;
import com.microsoft.tfs.core.clients.versioncontrol.exceptions.ServerPathFormatException;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.WorkingFolder;
import com.microsoft.tfs.core.clients.versioncontrol.soapextensions.Workspace;

public class WorkfoldCommand extends Command {
	public WorkfoldCommand(TFSConnectionFactory connectionFactory) {
		super(connectionFactory);
	}

	public WorkfoldCommand() {
		super();
	}

	@Override
	public void run(final Map<String, String> parsedArgs,
			final List<String> regularArgs, String username, String password)
			throws Exception {
		if (parsedArgs.containsKey("-map"))
			mapWorkspace(parsedArgs.get("-server"), username, password,
					parsedArgs.get("-workspace"), regularArgs.get(0),
					regularArgs.get(1));
		else if (parsedArgs.containsKey("-unmap"))
			unmapWorkspace(parsedArgs.get("-server"), username, password,
					parsedArgs.get("-workspace"), regularArgs.get(0));
	}

	/**
	 * Creates a mapping between a workspace on the server and a local folder.
	 * 
	 * @param server
	 *            The server on which the workspace resides.
	 * @param usernameAndDomain
	 *            The username to use when connecting to the server.
	 * @param password
	 *            The password to use when connecting to the server.
	 * @param workspaceName
	 *            The name of the workspace to map.
	 * @param serverDirectory
	 *            The directory on the server to map.
	 * @param localDirectory
	 *            The local directory to map.
	 */
	public void mapWorkspace(final String server,
			final String usernameAndDomain, final String password,
			final String workspaceName, final String serverDirectory,
			final String localDirectory) {
		connectionFactory
				.createConnection(server, usernameAndDomain, password)
				.getVersionControlClient()
				.queryWorkspace(workspaceName,
						VersionControlConstants.AUTHENTICATED_USER)
				.createWorkingFolder(
						new WorkingFolder(serverDirectory, localDirectory));
	}

	/**
	 * Removes a workspace mapping between a server folder and a local folder.
	 * 
	 * @param server
	 *            The server on which the workspace resides.
	 * @param usernameAndDomain
	 *            The username to use when connecting to the server.
	 * @param password
	 *            The password to use when connecting to the server.
	 * @param workspaceName
	 *            The name of the workspace whose working folders should be
	 *            unmapped.
	 * @param localOrServerDirectory
	 *            The local or server folder (this function will first try this
	 *            as a local folder and then, if that doesn't work, as a server
	 *            folder before giving up).
	 * @throws ServerPathFormatException
	 * @throws IOException
	 */
	public void unmapWorkspace(final String server,
			final String usernameAndDomain, final String password,
			final String workspaceName, final String localOrServerDirectory)
			throws ServerPathFormatException, IOException {
		unmapWorkspace(
				connectionFactory
						.createConnection(server, usernameAndDomain, password)
						.getVersionControlClient()
						.queryWorkspace(workspaceName,
								VersionControlConstants.AUTHENTICATED_USER),
				localOrServerDirectory);
	}

	/**
	 * Removes a workspace mapping between a server folder and a local folder.
	 * 
	 * @param workspace
	 *            The workspace whose mapping is to be removed.
	 * @param localOrServerDirectory
	 *            The local or server folder whose mapping should be removed.
	 *            This function will first try treating this variable as a local
	 *            folder. If no local folder can be found, this variable will
	 *            then be tried as a server folder.
	 * @throws IOException
	 * @throws ServerPathFormatException
	 */
	public void unmapWorkspace(final Workspace workspace,
			final String localOrServerDirectory)
			throws ServerPathFormatException, IOException {
		final WorkingFolder wf = workspace
				.getExactMappingForLocalPath(localOrServerDirectory);
		// If no local folder by that name could be found, it must be a server
		// folder.
		if (wf == null)
			workspace.deleteWorkingFolder(workspace
					.getExactMappingForServerPath(localOrServerDirectory));
		else
			workspace.deleteWorkingFolder(wf);
	}
}
